package com.gl.basis.common.pojo;

import com.alibaba.fastjson.JSON;
import com.gl.basis.common.util.BeanUtil;

import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分页模型
 *
 * @param <T> T泛型:最终查询出来需要返回的结果对象
 */
public class Page<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private static final String SUCCESS_CODE = "0000";
    private static final String SUCCESS_MESSAGE = "操作成功";
    private static final String FAIL_CODE = "9999";
    private static final String FAIL_MESSAGE = "操作失败";
    private static final String __PAGENO__ = "__pageNo__";
    private static final String __PAGESIZE__ = "__pageSize__";
    private static final String __ORDERBY__ = "__orderBy__";

    private Boolean isPage = false;//是否分頁，默认不分页
    private Integer pageNo = 1;
    private Integer pageSize = 10;//每页显示数
    private Long totalSize;//总记录数
    private int pages; //总页数
    private String order;
    private String orderDesc = "asc";
    private final Map<String, Object> params = new HashMap<>(0);//查询条件
    private String code;
    private String msg;
    private Boolean success = true;
    private T t;
    private List<T> list;
    private Object result;
    private Map<String, Object> map = new HashMap<>();


    /**
     * 联盟id
     */
    private String allianceId;

    public String getAllianceId() {
        return allianceId;
    }

    public void setAllianceId(String allianceId) {
        this.allianceId = allianceId;
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getMsg() {
        if (msg == null || msg.trim().length() == 0) {
            msg = success ? SUCCESS_MESSAGE : FAIL_MESSAGE;
        }
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getCode() {
        if (code == null || code.trim().length() == 0) {
            code = success ? SUCCESS_CODE : FAIL_CODE;
        }
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        if (list != null && list instanceof com.github.pagehelper.Page) {
            com.github.pagehelper.Page<T> pager = (com.github.pagehelper.Page<T>) list;
            this.setTotalSize(pager.getTotal());
            this.setPages(pager.getPages());
        }
        this.list = list;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public Map<String, Object> getParams() {
        return this.params;
    }

    public void setParams(Map<String, Object> params) {
        if (params == null || params.isEmpty()) {
            return;
        }
        if (this.getIsPage()) {
            if (!params.containsKey(__PAGESIZE__)) {
                params.put(__PAGESIZE__, this.getPageSize());
            }
            if (!params.containsKey(__PAGENO__)) {
                params.put(__PAGENO__, this.getPageNo());
            }
        }
        this.params.putAll(params);
    }

    public Integer getPageNo() {
        return pageNo;
    }

    public void setPageNo(Integer pageNo) {
        this.pageNo = pageNo;
        this.setIsPage(this.isPage);
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
        this.setIsPage(this.isPage);
    }

    public Long getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(Long totalSize) {
        this.totalSize = totalSize;
    }

    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
        if (order != null && order.trim().length() != 0) {
            this.params.put(__ORDERBY__, order + " " + this.getOrderDesc());
        }
    }

    public String getOrderDesc() {
        return orderDesc;
    }

    public void setOrderDesc(String orderDesc) {
        this.orderDesc = orderDesc;
        this.setOrder(order);
    }

    public Boolean getIsPage() {
        return isPage;
    }

    public void setIsPage(Boolean isPage) {
        this.isPage = isPage;
        if (this.isPage) {
            this.params.put(__PAGENO__, this.getPageNo());
            this.params.put(__PAGESIZE__, this.getPageSize());
        }
    }

    /**
     * 后台强制分页
     */
    public void startPage() {
        this.setIsPage(true);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo 当前页
     */
    public void startPage(Integer pageNo) {
        this.setPageNo(pageNo);
        this.setIsPage(true);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo 当前页
     * @param order  排序字段 数据库同名
     */
    public void startPage(Integer pageNo, String order) {
        this.setPageNo(pageNo);
        this.setIsPage(true);
        this.setOrder(order);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo    当前页
     * @param order     排序字段 数据库同名
     * @param orderDesc 排序顺序
     */
    public void startPage(Integer pageNo, String order, String orderDesc) {
        this.setPageNo(pageNo);
        this.setIsPage(true);
        this.orderBy(order, orderDesc);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo   当前页
     * @param pageSize 分页条数
     */
    public void startPage(Integer pageNo, Integer pageSize) {
        this.setPageNo(pageNo);
        this.setPageSize(pageSize);
        this.setIsPage(true);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo   当前页
     * @param pageSize 分页条数
     * @param order    排序字段 数据库同名
     */
    public void startPage(Integer pageNo, Integer pageSize, String order) {
        this.setPageNo(pageNo);
        this.setPageSize(pageSize);
        this.setIsPage(true);
        this.orderBy(order);
    }

    /**
     * 后台强制分页
     *
     * @param pageNo    当前页
     * @param pageSize  分页条数
     * @param order     排序字段 数据库同名
     * @param orderDesc 排序顺序
     */
    public void startPage(Integer pageNo, Integer pageSize, String order, String orderDesc) {
        this.setPageNo(pageNo);
        this.setPageSize(pageSize);
        this.setIsPage(true);
        this.orderBy(order, orderDesc);
    }

    /**
     * 排序
     *
     * @param order 排序字段 数据库同名
     */
    public void orderBy(String order) {
        this.setOrder(order);
    }

    /**
     * 排序
     *
     * @param order     排序字段 数据库同名
     * @param orderDesc 排序顺序
     */
    public void orderBy(String order, String orderDesc) {
        this.setOrder(order);
        this.setOrderDesc(orderDesc);
    }

    public int getPages() {
        return pages;
    }

    public void setPages(int pages) {
        this.pages = pages;
    }

    public Object getResult() {
        return (result != null ? result : SUCCESS_CODE);
    }

    public String gtResultString() {
        if (result != null) {
            if (result instanceof String) {
                return (String) result;
            } else {
                return JSON.toJSONString(result);
            }
        } else {
            return null;
        }
    }

    public static Page convertParam(Map<String, Object> params) {
        Page pageParam = new Page();
        pageParam.setParams(params);
        return pageParam;
    }

    public static Page convertMapParam(Object params) {
        Page pageParam = new Page();
        if (!(params instanceof Map)) {
            pageParam.setParams(BeanUtil.transBean2Map(params));
        } else {
            pageParam.setParams((Map) params);
        }

        return pageParam;
    }

    public Object gtResult() {
        return result;
    }

    public Object gtResult(Class<T> clzz) {
        if (result == null || "0000".equals(result)) {
            return null;
        }
        if (result instanceof List) {
            return JSON.parseArray(JSON.toJSONString(result), clzz);
        }
        return JSON.parseObject(JSON.toJSONString(result), clzz);
    }

    public void setResult(Object obj) {
        this.result = obj;
        if (obj != null && obj instanceof List && obj instanceof com.github.pagehelper.Page) {
            com.github.pagehelper.Page<T> pager = (com.github.pagehelper.Page<T>) obj;
            this.setTotalSize(pager.getTotal());
            this.setPages(pager.getPages());
        }
    }

    private String unescapeJava(String str) {
        Writer out = new StringWriter();
        try {
            if (str != null) {
                int sz = str.length();
                StringBuilder unicode = new StringBuilder(4);
                boolean hadSlash = false;
                boolean inUnicode = false;

                for (int i = 0; i < sz; ++i) {
                    char ch = str.charAt(i);
                    if (inUnicode) {
                        unicode.append(ch);
                        if (unicode.length() == 4) {
                            try {
                                int nfe = Integer.parseInt(unicode.toString(), 16);
                                out.write((char) nfe);
                                unicode.setLength(0);
                                inUnicode = false;
                                hadSlash = false;
                            } catch (NumberFormatException var9) {
                            }
                        }
                    } else if (hadSlash) {
                        hadSlash = false;
                        switch (ch) {
                            case '\"':
                                out.write(34);
                                break;
                            case '\'':
                                out.write(39);
                                break;
                            case '\\':
                                out.write(92);
                                break;
                            case 'b':
                                out.write(8);
                                break;
                            case 'f':
                                out.write(12);
                                break;
                            case 'n':
                                out.write(10);
                                break;
                            case 'r':
                                out.write(13);
                                break;
                            case 't':
                                out.write(9);
                                break;
                            case 'u':
                                inUnicode = true;
                                break;
                            default:
                                out.write(ch);
                        }
                    } else if (ch == 92) {
                        hadSlash = true;
                    } else {
                        out.write(ch);
                    }
                }

                if (hadSlash) {
                    out.write(92);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return out.toString();
    }

    public Boolean isSuccess() {
        if (SUCCESS_CODE.equals(this.code)) {
            return true;
        }
        return false;
    }
}
